package com.ux.iot.core.service.scan;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import com.ux.iot.core.annotation.IotScan;
import com.ux.iot.core.annotation.MessageListener;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author caixiaodao
 * @version 1.0
 * 功能描述
 * iot 注解扫描类
 * @date 2021/12/5 10:40
 */
@Slf4j
public class IotScanRegister implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanFactoryAware {
        private ResourceLoader resourceLoader;

        private BeanFactory beanFactory;

        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }

        @Override
        public void setResourceLoader(@NonNull ResourceLoader resourceLoader) {
            this.resourceLoader = resourceLoader;
        }

        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, @NonNull BeanDefinitionRegistry registry) {

            AnnotationAttributes mapperScanAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(IotScan.class.getName()));
            if (mapperScanAttrs == null)  return;

            this.registerBeanDefinitions(mapperScanAttrs, registry);
        }


        private Set<BeanDefinitionHolder> registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry) {
            List<String> basePackages = new ArrayList<>();
            //取到所有属性的值
            basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText).collect(Collectors.toList()));
            basePackages.addAll(Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName).collect(Collectors.toList()));
            IotScanner scanner = new IotScanner(registry);
            scanner.setBeanNameGenerator((beanDefinition,beanDefinitionRegistry)->{
                String beanClassName = beanDefinition.getBeanClassName();
                try {
                    Class<?> clz = Class.forName(beanClassName);
                    log.info("加载的topic 处理类 {}",clz.getSimpleName());
                    MessageListener at = clz.getAnnotation(MessageListener.class);
                    if (null == at){
                        return "nullMessageListener"+ UUID.randomUUID();
                    }
                    String beanName=ObjectUtil.isNotEmpty(at.topic())?at.topic():at.value();
                    String key = Base64.encode(beanName);
                    return  key;
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    return null;
                }
            });
            if(resourceLoader != null){
                scanner.setResourceLoader(resourceLoader);
            }
            return scanner.doScan(StringUtils.toStringArray(basePackages));
        }




    }
